AbstractVersioningStrategy.java
package org.codefilarete.stalactite.engine.runtime;
import org.codefilarete.stalactite.engine.VersioningStrategy;
import org.codefilarete.tool.function.Serie;
import org.codefilarete.reflection.Mutator;
import org.codefilarete.reflection.ReversibleAccessor;
/**
* A template for implementing a {@link VersioningStrategy} that let user defines type of the versioning attribute and its sequence.
* See {@link VersioningStrategySupport} for a complete implementation.
*
* @param <C> versioned entity type
* @param <V> versioning attribute type
* @author Guillaume Mary
*/
public abstract class AbstractVersioningStrategy<C, V> implements VersioningStrategy<C, V>, Serie<V> {
private final ReversibleAccessor<C, V> versionAccessor;
/** {@link Mutator} took from {@link #versionAccessor} to prevent to ask for it at every upgrade because the toMutator() may be costly */
private final Mutator<C, V> versionMutator;
public AbstractVersioningStrategy(ReversibleAccessor<C, V> versioningAttributeAccessor) {
this.versionAccessor = versioningAttributeAccessor;
this.versionMutator = versionAccessor.toMutator();
}
@Override
public ReversibleAccessor<C, V> getVersionAccessor() {
return versionAccessor;
}
@Override
public V getVersion(C o) {
return versionAccessor.get(o);
}
@Override
public V upgrade(C o) {
V currentVersion = getVersion(o);
V nextVersion = next(currentVersion);
versionMutator.set(o, nextVersion);
return currentVersion;
}
@Override
public V revert(C o, V previousValue) {
V currentVersion = getVersion(o);
versionMutator.set(o, previousValue);
return currentVersion;
}
/**
* {@link VersioningStrategy} for simple cases
*
* @param <E> versioned entity type
* @param <V> versioning attribute type
*/
public static class VersioningStrategySupport<E, V> extends AbstractVersioningStrategy<E, V> {
private final Serie<V> sequence;
public VersioningStrategySupport(ReversibleAccessor<E, V> versioningAttributeAccessor, Serie<V> sequence) {
super(versioningAttributeAccessor);
this.sequence = sequence;
}
@Override
public V next(V previousVersion) {
return sequence.next(previousVersion);
}
}
}